package com.edu.test;

import com.edu.bean.User;
import org.junit.Test;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/*
 * @Author:mx
 * @Date:2025/11/4-16:22:55
 */
public class MyTest04 {

    /*
    *   获取 一个 class文件 内部 包含的方法的信息
    *          在Java反射中 使用 Method类型来描述一个方法的信息。
    *          获取Method对象 通过 Class对象获取
    *               getMethods 获取 其所有的公有的方法（包括其 父类 和接口的方法）
    *               getDeclaredMethods(); 获取其所有的共有和私有方法 （不包括父类）
    *               getMethod(String name,Class...paraType) 根据方法名和参数类型 获取公有方法
    *               getDeclaredMethod 根据方法名和参数类型 获取公有/私有方法
    * */
    @Test
    public void test01() throws NoSuchMethodException {
        Class clazz = User.class;
//        Method[] methods = clazz.getMethods();
//        System.out.println(methods.length);
//        for (Method method : methods) {
//            System.out.println(method.getName());
//        }

//        Method[] methods = clazz.getDeclaredMethods();
//        System.out.println(methods.length);
//        for (Method method : methods) {
//            System.out.println(method.getName());
//        }

//        clazz.getMethod

        Method m1 = clazz.getMethod("sayHi");//获取 无参数的 sayHi方法
        System.out.println(m1.getName());
        System.out.println(m1.getParameterTypes().length);

        Method m2 = clazz.getMethod("sayHi",String.class);
        System.out.println(m2);
        System.out.println(m2.getParameterCount());

        Method m3 = clazz.getMethod("sayHi",String.class,int.class);
        System.out.println(m3.getName());
        System.out.println(m3.getParameterCount());

//        Method m4 = clazz.getMethod("sayPrivate");//无法获取私有方法

        Method sayPrivate = clazz.getDeclaredMethod("sayPrivate");
    }

    /*
    *   Method 的一些常用方法
    *
    *
    * */
    @Test
    public void test02() throws NoSuchMethodException {
        Class clazz = User.class;
        for (Method method : clazz.getDeclaredMethods()) {
            System.out.println("方法名:"+method.getName());
            System.out.println("参数列表");
            for (Class<?> parameterType : method.getParameterTypes()) {
                System.out.println(parameterType.getName());
            }
            System.out.println("返回值类型:"+method.getReturnType());
            System.out.println("修饰符:"+method.getModifiers());
            System.out.println("-----------");
        }
    }

    /*
    *   Method的调用
    *       方法对象.invoke()
    *
    * */

    @Test
    public void test03() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class clazz = User.class;
        User user1 = new User();
        User user2 = new User();
        user1.userId = 10;
        user2.userId = 20;
//        Method method = clazz.getMethod("sayHi");
//        method.invoke(user1);

//        Method m2 = clazz.getMethod("sayHi",String.class);
//        m2.invoke(user1,"中午吃啥");

        Method m3 =  clazz.getMethod("sayHi",String.class,int.class);
        System.out.println(m3.invoke(user1,"好饿",3));

        Method m4 = clazz.getMethod("getUserId");
        Object o = m4.invoke(user1);
        System.out.println(o);

        Method m5 = clazz.getDeclaredMethod("sayPrivate");
        m5.setAccessible(true);
        m5.invoke(user1);
        System.out.println(m5.getDeclaringClass());

        Method m6 = clazz.getMethod("toString");
        System.out.println(m6.getDeclaringClass());
    }

}
